﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;

namespace Pasta.Medio
{
	/// <summary>
	/// Local configuration stored in 
	/// </summary>
	/// <example>
	/// Retrieve a local configuration
	///		LocalConfig config = new LocalConfig( "Sciformatix", "SciLims" );
	/// Set configuration key
	///		config["DefaultSkin"] = "Blue";
	/// Configuration section
	///		section = config.GetSection( "LocalPrinters" );
	///		section["Zebra"] = "\\PrtnSvr\ZebraS4M";
	///		
	/// <?xml version="1.0" encoding="utf-8"?>
	/// <configuration>
	///   <configSections>
	///     <section name="SciLims" type="System.Configuration.AppSettingsSection, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" allowExeDefinition="MachineToLocalUser" />
	///     <section name="LocalPrinters" type="System.Configuration.AppSettingsSection, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" allowExeDefinition="MachineToLocalUser" />
	///   </configSections>
	///   <SciLims>
	///     <add key="DefaultSkin" value="Blue" />
	///   </SciLims>
	///   <LocalPrinters>
	///     <add key="Zebra 2844" value="\\Zeus\Zebra2844-1" />
	///     <add key="Intermec 3240" value="\\Zeus\EasyCoder3240-1" />
	///   </LocalPrinters>
	/// </configuration>
	///
	/// </example>
	public class Config
	{
		public Configuration Configuration { get; set; }

		public string Company { get; set; }
		public string Product { get; set; }

		public Config(string company, string product)
		{
			Company = company;
			Product = product;
			string configDir = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
			string companyDir = Path.Combine(configDir, company);
			if (!Directory.Exists(companyDir))
			{
				Directory.CreateDirectory(companyDir);
			}
			ExeConfigurationFileMap configFileMap = new ExeConfigurationFileMap();
			product = Path.ChangeExtension(product, ".config");
			configFileMap.ExeConfigFilename = Path.Combine(companyDir, product);
			Configuration = ConfigurationManager.OpenMappedExeConfiguration(configFileMap, ConfigurationUserLevel.None);
		}

		/// <summary>
		/// A product level configuration setting
		/// </summary>
		/// <param name="key"></param>
		/// <returns></returns>
		public string this[string key]
		{
			get
			{
				string value = string.Empty;
				ConfigSection ls = GetSection(Product);
				if (ls != null)
				{
					value = ls[key];
				}
				return value;
			}
			set
			{
				ConfigSection ls = GetSection(Product);
				if (ls != null)
				{
					ls[key] = value;
				}
			}
		}

		/// <summary>
		/// Retreive a named section
		/// </summary>
		/// <param name="sectionName"></param>
		/// <returns></returns>
		public ConfigSection GetSection(string sectionName)
		{
			return new ConfigSection(this, sectionName);
		}

		public AppSettingsSection GetAppSection(string sectionName)
		{
			AppSettingsSection section;
			sectionName = sectionName.Replace(' ', '_');
			if (Configuration.Sections[sectionName] == null)
			{
				section = new AppSettingsSection();
				//				section.SectionInformation.AllowExeDefinition = ConfigurationAllowExeDefinition.MachineToLocalUser;
				Configuration.Sections.Add(sectionName, section);
			}
			else
			{
				section = (AppSettingsSection)Configuration.Sections[sectionName];
			}
			Configuration.Save(ConfigurationSaveMode.Minimal);
			return section;
		}

		public Dictionary<string, string> ListKeyValuePairs(string section)
		{
			AppSettingsSection settings = GetAppSection(section);
			Dictionary<string, string> kv = new Dictionary<string, string>();
			foreach (string key in settings.Settings.AllKeys)
			{
				kv[key] = settings.Settings[key].Value;
			}
			return kv;
		}

		public void Save()
		{
			Configuration.Save(ConfigurationSaveMode.Minimal);
		}
	}

	public class ConfigSection
	{
		private Config _config;
		private AppSettingsSection _section;

		/// <summary>
		/// Constructor for a section in the configuration with the name passed
		/// </summary>
		/// <param name="config">Configutation</param>
		/// <param name="sectionName">Section name</param>
		public ConfigSection(Config config, string sectionName)
		{
			_config = config;
			_section = config.GetAppSection(sectionName);
		}

		/// <summary>
		/// Indexer for a key in the section
		/// </summary>
		/// <param name="key">key</param>
		/// <returns>value</returns>
		public string this[string key]
		{
			get
			{
				string value = string.Empty;
				if (_section.Settings.AllKeys.Contains(key))
				{
					value = _section.Settings[key].Value;
				}
				return value;
			}
			set
			{
				if (_section.Settings.AllKeys.Contains(key))
					_section.Settings[key].Value = value;
				else
					_section.Settings.Add(key, value);
				_config.Save();
			}
		}
	}

}
